package com.shenqi.parking.service.impl;
import com.alibaba.fastjson2.JSONObject;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

/**
 * 使用OkHttp生成微信小程序码的服务类
 */
@Service
public class WechatMiniQrcodeService {

    private static final Logger log = LoggerFactory.getLogger(WechatMiniQrcodeService.class);

    @Autowired
    private WechatAccessTokenService accessTokenService;

    // 小程序码存储路径(若依框架通常使用profile路径)
    @Value("${ruoyi.profile}")
    private String profile;

    // 小程序码基础存储目录
    private static final String QRCODE_BASE_DIR = "/qrcode/mini/";

    // 获取小程序码的接口地址
    private static final String QRCODE_CREATE_URL = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s";

    // 初始化OkHttpClient
    private static final OkHttpClient okHttpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .readTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(10, TimeUnit.SECONDS)
            .build();

    /**
     * 生成小程序码并保存到服务器
     * @param page 页面路径（如 pages/detail/index）
     * @param scene 场景参数（如 id=123&type=2）
     * @return 保存的文件路径
     */
    public String generateQrcode(String page, String scene) {
        try {
            // 获取access_token
            String accessToken = accessTokenService.getAccessToken();
            if (accessToken == null || accessToken.isEmpty()) {
                throw new RuntimeException("获取access_token失败");
            }

            // 构建请求URL
            String url = String.format(QRCODE_CREATE_URL, accessToken);

            // 构建请求参数
            JSONObject params = new JSONObject();
            params.put("scene", scene);          // 场景参数
            params.put("page", page);            // 页面路径
            params.put("width", 430);            // 二维码宽度
            params.put("auto_color", false);     // 自动配置线条颜色
            params.put("is_hyaline", false);     // 是否透明底色

            // 创建请求体
            RequestBody requestBody = RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    params.toString()
            );

            // 构建请求
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();

            // 发送请求
            Response response = okHttpClient.newCall(request).execute();

            try {
                if (!response.isSuccessful()) {
                    throw new RuntimeException("生成小程序码失败，响应码: " + response.code());
                }

                ResponseBody body = response.body();
                if (body == null) {
                    throw new RuntimeException("生成小程序码失败，响应体为空");
                }

                // 检查返回的是否是图片（如果是错误，微信会返回JSON）
                MediaType mediaType = body.contentType();
                if (mediaType != null && mediaType.type().equals("image")) {
                    // 创建存储目录
                    String saveDir = profile + QRCODE_BASE_DIR;
                    Path dirPath = Paths.get(saveDir);
                    if (!Files.exists(dirPath)) {
                        Files.createDirectories(dirPath);
                    }

                    // 生成唯一文件名
                    String fileName = UUID.randomUUID().toString() + ".png";
                    String filePath = saveDir + fileName;

                    // 保存文件
                    try (InputStream inputStream = body.byteStream();
                         OutputStream outputStream = new FileOutputStream(filePath)) {

                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                    }

                    // 返回相对路径(用于前端访问)
                    return QRCODE_BASE_DIR + fileName;
                } else {
                    // 读取错误信息
                    String errorMsg = body.string();
                    throw new RuntimeException("生成小程序码失败: " + errorMsg);
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (Exception e) {
            log.error("生成小程序码异常", e);
            throw new RuntimeException("生成小程序码异常: " + e.getMessage(), e);
        }
    }

    /**
     * 生成小程序码并直接输出到响应流(用于前端下载)
     * @param page 页面路径
     * @param scene 场景参数
     * @param response 响应对象
     */
    public void generateQrcodeToResponse(String page, String scene, HttpServletResponse response) {
        try {
            // 获取access_token
            String accessToken = accessTokenService.getAccessToken();
            if (accessToken == null || accessToken.isEmpty()) {
                throw new RuntimeException("获取access_token失败");
            }

            // 构建请求URL
            String url = String.format(QRCODE_CREATE_URL, accessToken);

            // 构建请求参数
            JSONObject params = new JSONObject();
            params.put("scene", scene);
            params.put("page", page);
            params.put("width", 430);
            params.put("auto_color", false);
            params.put("is_hyaline", false);

            // 创建请求体
            RequestBody requestBody = RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    params.toString()
            );

            // 构建请求
            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();

            // 发送请求
            Response responseOk = okHttpClient.newCall(request).execute();

            try {
                if (!responseOk.isSuccessful()) {
                    throw new RuntimeException("生成小程序码失败，响应码: " + responseOk.code());
                }

                ResponseBody body = responseOk.body();
                if (body == null) {
                    throw new RuntimeException("生成小程序码失败，响应体为空");
                }

                // 检查返回的是否是图片
                MediaType mediaType = body.contentType();
                if (mediaType != null && mediaType.type().equals("image")) {
                    // 设置响应头
                    response.setContentType(mediaType.toString());
                    response.setHeader("Content-Disposition",
                            "attachment; filename=" + java.net.URLEncoder.encode("小程序码.png", "UTF-8"));

                    // 写入响应流
                    try (InputStream inputStream = body.byteStream();
                         OutputStream outputStream = response.getOutputStream()) {

                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                        outputStream.flush();
                    }
                } else {
                    // 读取错误信息
                    String errorMsg = body.string();
                    throw new RuntimeException("生成小程序码失败: " + errorMsg);
                }
            } finally {
                if (responseOk != null) {
                    responseOk.close();
                }
            }
        } catch (Exception e) {
            log.error("生成小程序码并输出异常", e);
            throw new RuntimeException("生成小程序码并输出异常: " + e.getMessage(), e);
        }
    }

    /**
     * 【核心优化】生成小程序码，返回二进制数组（不依赖HTTP响应）
     */
    public byte[] generateQrcodeBytes(String page, String scene) {
        try {
            String accessToken = accessTokenService.getAccessToken();
            if (accessToken == null || accessToken.isEmpty()) {
                throw new RuntimeException("获取access_token失败");
            }

            String url = String.format(QRCODE_CREATE_URL, accessToken);

            JSONObject params = new JSONObject();
            params.put("scene", scene);
            params.put("page", page);
            params.put("width", 430);
            params.put("auto_color", false);
            params.put("is_hyaline", false);

            RequestBody requestBody = RequestBody.create(
                    MediaType.parse("application/json; charset=utf-8"),
                    params.toString()
            );

            Request request = new Request.Builder()
                    .url(url)
                    .post(requestBody)
                    .build();

            Response response = okHttpClient.newCall(request).execute();

            try {
                if (!response.isSuccessful()) {
                    throw new RuntimeException("生成小程序码失败，响应码: " + response.code());
                }

                ResponseBody body = response.body();
                if (body == null) {
                    throw new RuntimeException("生成小程序码失败，响应体为空");
                }

                // 检查是否为图片类型（微信错误时返回JSON）
                MediaType mediaType = body.contentType();
                if (mediaType != null && mediaType.type().equals("image")) {
                    // 将输入流转为字节数组返回
                    try (InputStream inputStream = body.byteStream();
                         ByteArrayOutputStream outputStream = new ByteArrayOutputStream()) {
                        byte[] buffer = new byte[1024];
                        int bytesRead;
                        while ((bytesRead = inputStream.read(buffer)) != -1) {
                            outputStream.write(buffer, 0, bytesRead);
                        }
                        return outputStream.toByteArray();
                    }
                } else {
                    String errorMsg = body.string();
                    throw new RuntimeException("生成小程序码失败: " + errorMsg);
                }
            } finally {
                if (response != null) {
                    response.close();
                }
            }
        } catch (Exception e) {
            log.error("生成小程序码异常", e);
            throw new RuntimeException("生成小程序码异常: " + e.getMessage(), e);
        }
    }
}
